home *** CD-ROM | disk | FTP | other *** search
/ Power CD / Power CD ATARI-Rechner Lieben.iso / ALLERLEI / GOBJ_112 / UNITS / OBJECTS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-04-11  |  13.5 KB  |  614 lines

  1. {**************************************
  2.  *  O b j e c t G E M   Version 1.12  *
  3.  *  Copyright 1992-94 by Thomas Much  *
  4.  **************************************
  5.  *        Unit  O B J E C T S         *
  6.  **************************************
  7.  *    Softdesign Computer Software    *
  8.  *    Thomas Much, Gerwigstraße 46,   *
  9.  *  76131 Karlsruhe, (0721) 62 28 41  *
  10.  *         Thomas Much @ KA2          *
  11.  *  UK48@ibm3090.rz.uni-karlsruhe.de  *
  12.  **************************************
  13.  *    erstellt am:        13.07.1992  *
  14.  *    letztes Update am:  12.04.1994  *
  15.  **************************************}
  16.  
  17. {
  18.   WICHTIGE ANMERKUNGEN ZUM QUELLTEXT:
  19.  
  20.   ObjectGEM wird ab sofort mit dem _vollständigen_ Quelltext ausgeliefert,
  21.   d.h. jeder kann sich die Unit selbst compilieren, womit die extrem
  22.   lästigen Kompatibilitätsprobleme mit den PP-Releases beseitigt sind.
  23.   ObjectGEM ist und bleibt aber trotzdem SHAREWARE, d.h. wer die Biblio-
  24.   thek regelmäßig benutzt, muß sich REGISTRIEREN lassen (so wie bisher).
  25.   Im Moment gibt es dafür dann "nur" die neueste Version; eine geTEXte
  26.   Doku ist aber in Arbeit, so daß auch ein gedrucktes Handbuch immer
  27.   wahrscheinlicher wird.
  28.  
  29.   Der Quelltext enthält z.Z. noch _keine_ Kommentare; wer sich dennoch die
  30.   Mühe macht, ihn zu lesen, wird feststellen, daß er außerdem noch recht
  31.   "wirr" und teilweise umständlich geschrieben ist, oder daß er evtl. auch
  32.   unnötige Teile enthält. Das liegt daran, daß dieser Quelltext eigentlich
  33.   gar nicht für eine Veröffentlichung gedacht war, aber immer häufiger auf-
  34.   tretende PP-Updates haben mich schier zur Verzweiflung getrieben...
  35.   Das alles sollte aber kein Grund sein, ObjectGEM nicht einzusetzen, denn
  36.   sobald nach "außen" die von mir gewünschte Funktionalität erreicht ist
  37.   (d.h. wenn alle wichtigen Objekte vorhanden sind, z.B. TEditWindow etc.),
  38.   werde ich mich um die "innere" Optimierung kümmern (dazu gehören dann
  39.   auch die Kommentare). Die bisher geschriebenen ObjectGEM-Anwendungen
  40.   können dann natürlich weiterverwendet werden.
  41.  
  42.   Wer beim Durchstöbern des Textes auf vermeintliche Fehler oder verbesse-
  43.   rungswürdige Stellen trifft (von letzterem gibt es sicherlich noch viele),
  44.   kann mir dies gerne mitteilen - ich habe auch ich nichts gegen kostenlos
  45.   zur Verfügung gestellte optimierte Routinen (sofern sich jemand die Mühe
  46.   macht). Wer in anderen Projekten, die nicht in direkter Konkurrenz zu
  47.   ObjectGEM stehen, einzelne Routinen verwenden möchte, wendet sich bitte
  48.   an mich (ein solcher Austausch sollte kein Problem sein).
  49.  
  50.   Wer sich auf nicht dokumentierte "implementation"- oder "private"-Eigen-
  51.   schaften verläßt, darf sich nicht über Inkompatibilitäten zu späteren
  52.   Versionen wundern; wer meint, eine Dokumentationslücke entdeckt zu haben
  53.   (außer dem "Abgrund" des noch fehlenden Handbuchs...), kann mir dies
  54.   gerne mitteilen.
  55.  
  56.   WICHTIG: Wer den Quelltext verändert und dann Probleme beim Compilieren,
  57.   Ausführen o.ä. hat, kann nicht damit rechnen, daß ich den Fehler suche;
  58.   tritt der Fehler allerdings auch mit dem Original-Quelltext auf, würde
  59.   ich mich über eine genaue Fehlerbeschreibung freuen. Veränderte Quell-
  60.   texte dürfen _nicht_ weitergegeben werden, dies wäre ein Verstoß gegen
  61.   das Copyright!
  62.  
  63.   Kleine Info zum Schluß: Als "default tabsize" verwende ich 2. Wer drei
  64.   Punkte ("...") im Quelltext entdeckt, hat eine Stelle gefunden, an der
  65.   ich z.Z. arbeite ;-)
  66.  
  67.   "Möge die OOP mit Euch sein!"
  68. }
  69.  
  70.  
  71. {$IFDEF DEBUG}
  72.     {$B+,D+,G-,I-,L+,N-,P-,Q+,R+,S+,T-,V-,X+,Z+}
  73. {$ELSE}
  74.     {$B+,D-,G-,I-,L-,N-,P-,Q-,R-,S-,T-,V-,X+,Z+}
  75. {$ENDIF}
  76.  
  77. unit Objects;
  78.  
  79. interface
  80.  
  81. uses
  82.  
  83.     OTypes;
  84.  
  85. type
  86.  
  87.     PObject           = ^TObject;
  88.     TObject           = object
  89.         public
  90.         constructor Init;
  91.         procedure Free;
  92.         destructor Done; virtual;
  93.     end;
  94.  
  95.     PCollection       = ^TCollection;
  96.     TCollection       = object(TObject)
  97.         public
  98.         Items: PItemList;
  99.         Count,
  100.         Limit,
  101.         Delta: longint;
  102.         constructor Init(ALimit,ADelta: longint);
  103.         destructor Done; virtual;
  104.         function At(Index: longint): pointer; virtual;
  105.         procedure AtDelete(Index: longint); virtual;
  106.         procedure AtFree(Index: longint); virtual;
  107.         procedure AtInsert(Index: longint; Item: pointer); virtual;
  108.         procedure AtPut(Index: longint; Item: pointer); virtual;
  109.         procedure Delete(Item: pointer); virtual;
  110.         procedure Error(Code,Info: longint); virtual;
  111.         procedure DeleteAll; virtual;
  112.         function FirstThat(Test: PIterationFunc): pointer; virtual;
  113.         procedure ForEach(Action: PIterationProc); virtual;
  114.         procedure Free(Item: pointer);
  115.         procedure FreeAll; virtual;
  116.         procedure FreeItem(Item: pointer); virtual;
  117.         function IndexOf(Item: pointer): longint; virtual;
  118.         procedure Insert(Item: pointer); virtual;
  119.         function LastThat(Test: PIterationFunc): pointer; virtual;
  120.         procedure Pack; virtual;
  121.         procedure SetLimit(ALimit: longint); virtual;
  122.     end;
  123.  
  124.     PSortedCollection = ^TSortedCollection;
  125.     TSortedCollection = object(TCollection)
  126.         public
  127.         Duplicates: boolean;
  128.         constructor Init(ALimit,ADelta: longint);
  129.         function IndexOf(Item: pointer): longint; virtual;
  130.         procedure Insert(Item: pointer); virtual;
  131.         function Compare(Key1,Key2: pointer): integer; virtual;
  132.         function KeyOf(Item: pointer): pointer; virtual;
  133.         function Search(Key: pointer; var Index: longint): boolean; virtual;
  134.     end;
  135.  
  136.     PStringCollection = ^TStringCollection;
  137.     TStringCollection = object(TSortedCollection)
  138.         public
  139.         constructor Init(ALimit,ADelta: longint);
  140.         procedure FreeItem(Item: pointer); virtual;
  141.         function Compare(Key1,Key2: pointer): integer; virtual;
  142.     end;
  143.  
  144.     PStrCollection    = ^TStrCollection;
  145.     TStrCollection    = object(TStringCollection)
  146.         public
  147.         procedure FreeItem(Item: pointer); virtual;
  148.         function Compare(Key1,Key2: pointer): integer; virtual;
  149.     end;
  150.  
  151.  
  152.  
  153. implementation
  154.  
  155. uses
  156.  
  157.     Strings,OProcs;
  158.  
  159.  
  160. { *** Objekt TOBJECT *** }
  161.  
  162. constructor TObject.Init;
  163.  
  164.   begin
  165.   end;
  166.  
  167.  
  168. procedure TObject.Free;
  169.  
  170.     begin
  171.         dispose(PObject(@self),Done)
  172.     end;
  173.  
  174.  
  175. destructor TObject.Done;
  176.  
  177.   begin
  178.   end;
  179.  
  180. { *** TOBJECT *** }
  181.  
  182.  
  183.  
  184. { *** Objekt TCOLLECTION *** }
  185.  
  186. constructor TCollection.Init(ALimit,ADelta: longint);
  187.  
  188.     begin
  189.         if not(inherited Init) then fail;
  190.         Items:=nil;
  191.         Count:=0;
  192.         Limit:=0;
  193.         Delta:=ADelta;
  194.         if Delta<0 then Delta:=0;
  195.         SetLimit(ALimit)
  196.     end;
  197.  
  198.  
  199. destructor TCollection.Done;
  200.  
  201.     begin
  202.         FreeAll;
  203.         SetLimit(0);
  204.         inherited Done
  205.     end;
  206.  
  207.  
  208. function TCollection.At(Index: longint): pointer;
  209.  
  210.     begin
  211.         if (Index<0) or (Index>=Count) then
  212.             begin
  213.                 At:=nil;
  214.                 Error(coIndexError,Index)
  215.             end
  216.         else
  217.             At:=Items^[Index]
  218.     end;
  219.  
  220.  
  221. procedure TCollection.AtDelete(Index: longint);
  222.     var q: longint;
  223.  
  224.     begin
  225.         if (Index<0) or (Index>=Count) then Error(coIndexError,Index)
  226.         else
  227.             begin
  228.                 if Index<Count-1 then
  229.                     for q:=Index to (Count-2) do Items^[q]:=Items^[q+1];
  230.                 dec(Count)
  231.             end
  232.     end;
  233.  
  234.  
  235. procedure TCollection.AtFree(Index: longint);
  236.     var p: pointer;
  237.  
  238.     begin
  239.         p:=At(Index);
  240.         AtDelete(Index);
  241.         FreeItem(p)
  242.     end;
  243.  
  244.  
  245. procedure TCollection.AtInsert(Index: longint; Item: pointer);
  246.     var q: longint;
  247.  
  248.     begin
  249.         if (Index<0) or (Index>Count) then Error(coIndexError,Index)
  250.         else
  251.             begin
  252.                 if Count=Limit then SetLimit(Limit+Delta);
  253.                 if Count<Limit then
  254.                     begin
  255.                         if Index<Count then
  256.                             for q:=Count downto Index+1 do Items^[q]:=Items^[q-1];
  257.                         Items^[Index]:=Item;
  258.                         inc(Count)
  259.                     end
  260.                 else
  261.                     if Delta=0 then Error(coIndexError,Index)
  262.             end
  263.     end;
  264.  
  265.  
  266. procedure TCollection.AtPut(Index: longint; Item: pointer);
  267.  
  268.     begin
  269.         if (Index<0) or (Index>=Count) then Error(coIndexError,Index)
  270.         else
  271.             Items^[Index]:=Item
  272.     end;
  273.  
  274.  
  275. procedure TCollection.Delete(Item: pointer);
  276.  
  277.     begin
  278.         AtDelete(IndexOf(Item))
  279.     end;
  280.  
  281.  
  282. procedure TCollection.Error(Code,Info: longint);
  283.  
  284.     begin
  285.         case Code of
  286.             coIndexError: write('Index Range Error (',Info,') ');
  287.             coOverflow:   write('Collection Overflow (',Info,') ')
  288.         end;
  289.         runerror(212-Code)
  290.     end;
  291.  
  292.  
  293. procedure TCollection.DeleteAll;
  294.  
  295.     begin
  296.         Count:=0
  297.     end;
  298.  
  299.  
  300. function TCollection.FirstThat(Test: PIterationFunc): pointer;
  301.     var q : longint;
  302.         p : pointer;
  303.         cl: IterationFunc;
  304.  
  305.     begin
  306.         FirstThat:=nil;
  307.         cl:=IterationFunc(Test);
  308.         if Count>0 then
  309.             for q:=0 to Count-1 do
  310.                 begin
  311.                     p:=At(q);
  312.                     if p<>nil then
  313.                         if cl(p) then
  314.                             begin
  315.                                 FirstThat:=p;
  316.                                 exit
  317.                             end
  318.                 end
  319.     end;
  320.  
  321.  
  322. procedure TCollection.ForEach(Action: PIterationProc);
  323.     var q : longint;
  324.         p : pointer;
  325.         cl: IterationProc;
  326.  
  327.     begin
  328.         cl:=IterationProc(Action);
  329.         if Count>0 then
  330.             for q:=0 to Count-1 do
  331.                 begin
  332.                     p:=At(q);
  333.                     if p<>nil then cl(p)
  334.                 end
  335.     end;
  336.  
  337.  
  338. procedure TCollection.Free(Item: pointer);
  339.  
  340.     begin
  341.         Delete(Item);
  342.         FreeItem(Item)
  343.     end;
  344.  
  345.  
  346. procedure TCollection.FreeAll;
  347.     var q: longint;
  348.  
  349.     begin
  350.         if Count>0 then
  351.             for q:=0 to Count-1 do FreeItem(At(q));
  352.         Count:=0
  353.     end;
  354.  
  355.  
  356. procedure TCollection.FreeItem(Item: pointer);
  357.  
  358.     begin
  359.         if Item<>nil then PObject(Item)^.Free
  360.     end;
  361.  
  362.  
  363. function TCollection.IndexOf(Item: pointer): longint;
  364.     var q: longint;
  365.  
  366.     begin
  367.         IndexOf:=-1;
  368.         if Count>0 then
  369.             for q:=0 to Count-1 do
  370.                 if Item=At(q) then
  371.                     begin
  372.                         IndexOf:=q;
  373.                         exit
  374.                     end
  375.     end;
  376.  
  377.  
  378. procedure TCollection.Insert(Item: pointer);
  379.  
  380.     begin
  381.         AtInsert(Count,Item)
  382.     end;
  383.  
  384.  
  385. function TCollection.LastThat(Test: PIterationFunc): pointer;
  386.     var q : longint;
  387.         p : pointer;
  388.         cl: IterationFunc;
  389.  
  390.     begin
  391.         LastThat:=nil;
  392.         cl:=IterationFunc(Test);
  393.         if Count>0 then
  394.             for q:=Count-1 downto 0 do
  395.                 begin
  396.                     p:=At(q);
  397.                     if p<>nil then
  398.                         if cl(p) then
  399.                             begin
  400.                                 LastThat:=p;
  401.                                 exit
  402.                             end
  403.                 end
  404.     end;
  405.  
  406.  
  407. procedure TCollection.Pack;
  408.     label _again;
  409.  
  410.     var low,cur,pc,q: longint;
  411.  
  412.     begin
  413.         if Count>0 then
  414.             begin
  415.                 pc:=Count-1;
  416.                 low:=0;
  417.                 _again:
  418.                 while (Items^[low]<>nil) and (low<pc) do inc(low);
  419.                 cur:=low;
  420.                 while (Items^[cur]=nil) and (cur<pc) do inc(cur);
  421.                 if cur<pc then
  422.                     begin
  423.                         for q:=low to cur-1 do Items^[q]:=Items^[q+1];
  424.                         Items^[cur]:=nil;
  425.                         goto _again
  426.                     end;
  427.                 low:=0;
  428.                 while (low<Count) and (Items^[low]<>nil) do inc(low);
  429.                 Count:=low
  430.             end;
  431.         SetLimit(0)
  432.     end;
  433.  
  434.  
  435. procedure TCollection.SetLimit(ALimit: longint);
  436.     var dummy: PItemList;
  437.         q    : longint;
  438.  
  439.     begin
  440.         if ALimit<Count then ALimit:=Count;
  441.         if ALimit>MaxCollectionSize then ALimit:=MaxCollectionSize;
  442.         if ALimit<>Limit then
  443.             begin
  444.                 dummy:=nil;
  445.                 if ALimit>0 then getmem(dummy,ALimit shl 2);
  446.                 if (dummy<>nil) or (ALimit=0) then
  447.                     begin
  448.                         if (Items<>nil) and (dummy<>nil) and (Count>0) then
  449.                             for q:=0 to Count-1 do dummy^[q]:=Items^[q];
  450.                         if Items<>nil then freemem(Items,Limit shl 2);
  451.                         Limit:=ALimit;
  452.                         Items:=dummy
  453.                     end
  454.                 else
  455.                     if ALimit>Limit then Error(coOverflow,ALimit)
  456.             end
  457.     end;
  458.  
  459. { *** TCOLLECTION *** }
  460.  
  461.  
  462.  
  463. { *** Objekt TSORTEDCOLLECTION *** }
  464.  
  465. constructor TSortedCollection.Init(ALimit,ADelta: longint);
  466.  
  467.     begin
  468.         if not(inherited Init(ALimit,ADelta)) then fail;
  469.         Duplicates:=false
  470.     end;
  471.  
  472.  
  473. function TSortedCollection.IndexOf(Item: pointer): longint;
  474.     var i: longint;
  475.  
  476.     begin
  477.         if Search(KeyOf(Item),i) then IndexOf:=i
  478.         else
  479.             IndexOf:=-1
  480.     end;
  481.  
  482.  
  483. procedure TSortedCollection.Insert(Item: pointer);
  484.     var i: longint;
  485.  
  486.     begin
  487.         if not(Search(KeyOf(Item),i)) then AtInsert(i,Item)
  488.         else
  489.             begin
  490.                 if Duplicates then AtInsert(i,Item)
  491.                 else
  492.                     begin
  493.                         FreeItem(At(i));
  494.                         AtPut(i,Item)
  495.                     end;
  496.             end
  497.     end;
  498.  
  499.  
  500. function TSortedCollection.Compare(Key1,Key2: pointer): integer;
  501.  
  502.     begin
  503.         Compare:=0;
  504.         Abstract
  505.     end;
  506.  
  507.  
  508. function TSortedCollection.KeyOf(Item: pointer): pointer;
  509.  
  510.     begin
  511.         KeyOf:=Item
  512.     end;
  513.  
  514.  
  515. function TSortedCollection.Search(Key: pointer; var Index: longint): boolean;
  516.     var cur,low,high: longint;
  517.  
  518.     begin
  519.         Search:=false;
  520.         if Count>0 then
  521.             begin
  522.                 low:=0;
  523.                 high:=Count-1;
  524.                 cur:=high shr 1;
  525.                 repeat
  526.                     case Compare(Key,KeyOf(At(cur))) of
  527.                         0: begin
  528.                                  Index:=cur;
  529.                                  Search:=true;
  530.                                  exit
  531.                              end;
  532.                         1: if low=high then
  533.                                  begin
  534.                                      Index:=cur+1;
  535.                                      exit
  536.                                  end
  537.                              else
  538.                                  begin
  539.                                      low:=cur+1;
  540.                                      if low>high then low:=high;
  541.                                      cur:=(low+high) shr 1
  542.                                  end;
  543.                         -1: if low=high then
  544.                                     begin
  545.                                         Index:=cur;
  546.                                         exit
  547.                                     end
  548.                                 else
  549.                                     begin
  550.                                         high:=cur-1;
  551.                                         if high<low then high:=low;
  552.                                         cur:=(low+high) shr 1
  553.                                     end
  554.                     end
  555.                 until false
  556.             end
  557.         else
  558.             Index:=0
  559.     end;
  560.  
  561. { *** TSORTEDCOLLECTION *** }
  562.  
  563.  
  564.  
  565. { *** Objekt TSTRINGCOLLECTION *** }
  566.  
  567. constructor TStringCollection.Init(ALimit,ADelta: longint);
  568.  
  569.     begin
  570.         if not(inherited Init(ALimit,ADelta)) then fail;
  571.         Duplicates:=true
  572.     end;
  573.  
  574.  
  575. procedure TStringCollection.FreeItem(Item: pointer);
  576.  
  577.     begin
  578.         DisposeStr(PString(Item))
  579.     end;
  580.  
  581.  
  582. function TStringCollection.Compare(Key1,Key2: pointer): integer;
  583.  
  584.     begin
  585.         if PString(Key1)^>PString(Key2)^ then Compare:=1
  586.         else
  587.             if PString(Key1)^<PString(Key2)^ then Compare:=-1
  588.             else
  589.                 Compare:=0
  590.     end;
  591.  
  592. { *** TSTRINGCOLLECTION *** }
  593.  
  594.  
  595.  
  596. { *** Objekt TSTRCOLLECTION *** }
  597.  
  598. procedure TStrCollection.FreeItem(Item: pointer);
  599.  
  600.     begin
  601.         ChrDispose(PChar(Item))
  602.     end;
  603.  
  604.  
  605. function TStrCollection.Compare(Key1,Key2: pointer): integer;
  606.  
  607.     begin
  608.         Compare:=Sgn(StrComp(Key1,Key2))
  609.     end;
  610.  
  611. { *** TSTRCOLLECTION *** }
  612.  
  613.  
  614. end.